package com.jobcn.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;

public class IpAddressTool {

    private static final Logger logger = LoggerFactory.getLogger(IpAddressTool.class);

    /**
     * Jobcn公司的Internet的静态IP
     */
    public static final String[][] JOBCN_CO_IP = {{"59.39.253.98", "255.255.255.224"},
            {"218.16.124.66", "255.255.255.255"},
            {"218.16.124.67", "255.255.255.255"},
            {"218.16.124.68", "255.255.255.255"},
            {"218.16.124.69", "255.255.255.255"},
            {"218.16.124.70", "255.255.255.255"},
            {"218.16.124.71", "255.255.255.255"},
            {"218.16.124.72", "255.255.255.255"},
            {"218.16.124.99", "255.255.255.255"},
            {"218.16.124.100", "255.255.255.255"},
            {"192.168.0.1", "255.255.0.0"}
    };

    public static boolean isInJobcnCoNetSegment(String ip) {
        //for test @122 请不要把以下测试代码提交到SVN
        //if(ip.indexOf("192.168.61")>-1) return false;
        //if(ip.indexOf("192.168")>-1) return false;
        if (ip.equals("59.39.253.98") || ip.equals("59.39.253.99")) return false;

        boolean ret = false;

        for (int i = 0; i < JOBCN_CO_IP.length; i++) {
            if (isInSameNetSegment(ip, JOBCN_CO_IP[i][0], JOBCN_CO_IP[i][1])) {
                ret = true;
                break;
            }
        }

//        if(!ret) ret = JobcnGateWayUtil.isJobcnIp(ip); 
        return ret;
    }

    /**
     * 判断输入的两个IP地址是否在同一网段
     *
     * @param ip1  IP地址1
     * @param ip2  IP地址2
     * @param mask 子网掩码
     * @return 在同一网段：true；不在同一网段：false
     */
    public static boolean isInSameNetSegment(String ip1, String ip2, String mask) {
        boolean ret = false;
        try {
            byte[] aIp1 = null;
            byte[] aIp2 = null;
            byte[] aMask = null;
            aIp1 = getIpByteFromStr(ip1);
            aIp2 = getIpByteFromStr(ip2);
            aMask = getIpByteFromStr(mask);
            if (aIp1 != null && aIp2 != null && aMask != null) {
                ret = ((aIp1[0] & aMask[0]) == (aIp2[0] & aMask[0]));
                ret = ret && ((aIp1[1] & aMask[1]) == (aIp2[1] & aMask[1]));
                ret = ret && ((aIp1[2] & aMask[2]) == (aIp2[2] & aMask[2]));
                ret = ret && ((aIp1[3] & aMask[3]) == (aIp2[3] & aMask[3]));
            }
        } catch (Exception ex) {
            ret = false;
        }

        return ret;
    }

    /**
     * 根据输入的IP地址返回该IP地址的 byte[]，IP地址的高位字节在 getIpByteFromStr(ip)[0]。若IP地址串格式不正确返回 null。
     *
     * @param ip IP地址字符串
     * @return IP地址的 byte[]
     */
    public static byte[] getIpByteFromStr(String ip) {
        byte[] aBRet = null;
        InetAddress addr = null;
        try {
            addr = InetAddress.getByName(ip);
            aBRet = addr.getAddress();
        } catch (Exception ex) {
            aBRet = null;
            //ex.printStackTrace();
        }
        return aBRet;
    }


    /**
     * 返回客户端IP地址
     *
     * @param request HttpServletRequest
     * @return 客户端IP地址，若等于""，则表示取IP失败
     */
    public static String getRealRemoteIP(HttpServletRequest request) {
        String ret = "";
        String cdnSrcIp = request.getHeader("Cdn-Src-Ip");
        if (cdnSrcIp == null) {
            String ipNginx = request.getHeader("X_REAL_IP");
            String ip = null;
            if (ipNginx != null) {
                ip = ipNginx;
            } else {
                ip = request.getRemoteAddr();
            }
            if (ip != null) {
                ret = ip;
            }
        } else {
            ret = cdnSrcIp.trim();
        }

        if (ret.startsWith("0:0:0:0:")) {
            ret = "127.0.0.1";
        }
        return ret;
    }

    /**
     * 返回客户端IP地址
     *
     * @param request
     * @return 返回0表示取IP失败
     */
    public static long getRealRemoteIPLong(HttpServletRequest request) {
        String ret = getRealRemoteIP(request);
        if (!"".equals(ret)) {
            return ipToLong(ret);
        }
        return 0;
    }

    /**
     * 将127.0.0.1形式的IP地址转换成十进制整数，这里没有进行任何错误处理
     *
     * @param strIp
     * @return
     */
    public static long ipToLong(String strIp) {

        if (strIp.startsWith("0:0:0:0")) {
            strIp = "127.0.0.1";
        }

        try {
            long[] ip = new long[4];
            //先找到IP地址字符串中.的位置
            int position1 = strIp.indexOf(".");
            int position2 = strIp.indexOf(".", position1 + 1);
            int position3 = strIp.indexOf(".", position2 + 1);
            //将每个.之间的字符串转换成整型
            ip[0] = Long.parseLong(strIp.substring(0, position1));
            ip[1] = Long.parseLong(strIp.substring(position1 + 1, position2));
            ip[2] = Long.parseLong(strIp.substring(position2 + 1, position3));
            ip[3] = Long.parseLong(strIp.substring(position3 + 1));
            return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
        } catch (Exception e) {
            //logger.error(LogUtil.generateLogKey(), e);
        }
        return -1;
    }

    /**
     * 将十进制整数形式转换成127.0.0.1形式的ip地址
     *
     * @param longIp
     * @return
     */
    public static String longToIP(long longIp) {
        StringBuffer sb = new StringBuffer("");
        //直接右移24位
        sb.append(String.valueOf((longIp >>> 24)));
        sb.append(".");
        //将高8位置0，然后右移16位
        sb.append(String.valueOf((longIp & 0x00FFFFFF) >>> 16));
        sb.append(".");
        //将高16位置0，然后右移8位
        sb.append(String.valueOf((longIp & 0x0000FFFF) >>> 8));
        sb.append(".");
        //将高24位置0
        sb.append(String.valueOf((longIp & 0x000000FF)));
        return sb.toString();
    }
}
